

#import "NSMPhotosView.h"
#import "ZYQAssetPickerController.h"
#import "NSMPhotoBrowser.h"
#import <LFPhotoEditingController.h>

#define kPhotoViews [self mutableArrayValueForKeyPath:@"photoViews"]

@interface NSMPhotoImageView ()
@property (nonatomic) BOOL isDeleting;
@property (nonatomic, strong) UIButton *deleteBtn;
@property (nonatomic, copy) void(^deleteBtnActionBlock)(NSMPhotoImageView *sender);
@property (nonatomic, strong) LFPhotoEdit *photoEdit;
@end

@implementation NSMPhotoImageView
- (instancetype)init {
    self = [super init];
    if (self) {
        self.backgroundColor = GROUP_TABLECOLOR;
        _deleteBtn = [UIButton new];
        _deleteBtn.backgroundColor = WhiteColor(0, 0.5);
        _deleteBtn.size = CGSizeMake(64, 64);
        _deleteBtn.tintColor = COLOR_4;
        ViewCorner(_deleteBtn, 32);
        _deleteBtn.center = CGPointZero;
        [self addSubview:_deleteBtn];
        
        CGFloat icon_h = 28;
        CGFloat offset = 5;
        _deleteBtn.imageEdgeInsets = UIEdgeInsetsMake(_deleteBtn.height-icon_h - offset,
                                                      _deleteBtn.height-icon_h - offset,
                                                      offset,
                                                      offset);
        [_deleteBtn setImage:[BundleImage(@"nsm_delete_bucket") imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal];
        [_deleteBtn addTarget:self action:@selector(deleteBtnAction) forControlEvents:UIControlEventTouchUpInside];
        _deleteBtn.hidden = YES;
    }
    return self;
}

- (void)deleteBtnAction {
    !self.deleteBtnActionBlock?:self.deleteBtnActionBlock(self);
}

@end

@interface NSMPhotosView () <UIImagePickerControllerDelegate, UINavigationControllerDelegate, ZYQAssetPickerControllerDelegate, LFPhotoEditingControllerDelegate>
@property (nonatomic, strong) UIButton *addBtn;
@property (nonatomic, strong) NSMPhotoImageView *currentImageView;
@end

@implementation NSMPhotosView {
    BOOL            _isReplace;     // YES:替换,NO:新增
    UILabel         *_detailLabel;  // 描述文本
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self.backgroundColor = COLOR_4;
        self.orientation = MyOrientation_Vert;
        self.myHorzMargin = 0;
        self.wrapContentHeight = YES;
        self.arrangedCount = 3;
        self.subviewSpace = 12;
        self.gravity = MyGravity_Horz_Fill;
        self.padding = UIEdgeInsetsMake(15, 15, 15, 15);
        
        _aspectRatio = 1.0f;
        _deleteEnabled = NO;
        _maximumNumberOfPhotos = 3;
        _addPictureMode = NSMAddPictureModeAll;
        _photoViews = @[].mutableCopy;
        _placeholderImage = [UIImage imageWithColor:GROUP_TABLECOLOR size:CGSizeMake(100, 100)];
        
        [self addSubview:self.addBtn];
        self.editEnabled = NO;
        
        [_noteCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
    }
    return self;
}

+ (instancetype)photoView {
    return [[self alloc] init];
}

#pragma mark - setter/getters
- (void)setEditEnabled:(BOOL)editEnabled {
    _editEnabled = editEnabled;
    [self checkVisibility];
}

- (void)setMaximumNumberOfPhotos:(NSInteger)maximumNumberOfPhotos {
    _maximumNumberOfPhotos = maximumNumberOfPhotos;
    [self checkVisibility];
}

- (void)setOriginPhotos:(NSArray<id<NSObject>> *)originPhotos {
    self.photoViews = @[].mutableCopy;
    for (UIView *subView in self.subviews) {
        if (subView != self.addBtn) {
            [subView removeFromSuperview];
        }
    }
    [self addImageViews:originPhotos isOrigin:YES];
}

- (void)setAddImage:(UIImage *)addImage {
    [self.addBtn setBackgroundImage:addImage forState:UIControlStateNormal];
}

- (void)setAspectRatio:(CGFloat)aspectRatio {
    _aspectRatio = aspectRatio;
    
    for (UIView *view in self.subviews) {
        if ([view isKindOfClass:NSMPhotoImageView.class] ||
            (view == _addBtn)) {
            view.heightSize.equalTo(view.widthSize).multiply(_aspectRatio);
        }
    }
    [self layoutIfNeeded];
}

- (UIButton *)addBtn {
    if (!_addBtn) {
        _addBtn = [UIButton new];
        _addBtn.heightSize.equalTo(_addBtn.widthSize).multiply(_aspectRatio);
        _addBtn.adjustsImageWhenHighlighted = NO;
        [_addBtn setBackgroundImage:BundleImage(@"nsm_picture_add") forState:UIControlStateNormal];
        [_addBtn addTarget:self action:@selector(addButtonDidClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _addBtn;
}

- (CABasicAnimation *)shakeAnimation {
    CABasicAnimation *shake = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    shake.fromValue = @(-M_PI_4 * 0.05);
    shake.toValue = @(M_PI_4 * 0.05);
    shake.duration = 0.15;
    shake.autoreverses = YES;
    shake.repeatCount = MAXFLOAT;
    return shake;
}

- (void)addActionsForImageView:(NSMPhotoImageView *)imageView {
    @nsm_weak(self)
    if (!_editEnabled) {
        imageView.tapActionBlock = ^(NSMImageView *sender) {
            @nsm_strong(self)
            self.currentImageView = (NSMPhotoImageView *)sender;
            [self browseImage];
        };
        return;
    }
    
    // 单击浏览
    imageView.tapActionBlock = ^(NSMImageView *sender) {
        @nsm_strong(self)
        self.currentImageView = (NSMPhotoImageView *)sender;
        if (!((NSMPhotoImageView *)sender).isDeleting)
            [self imageViewDidTap:(NSMPhotoImageView *)sender];
        else {
            self.addBtn.enabled = YES;
            for (UIView *view in self.subviews) {
                if ([view isKindOfClass:[NSMPhotoImageView class]]) {
                    ((NSMPhotoImageView *)view).isDeleting = NO;
                    ((NSMPhotoImageView *)view).deleteBtn.hidden = YES;
                    [view.layer removeAllAnimations];
                }
            }
        }
    };
    
    // 长按抖动
    imageView.longPressActionBlock = ^(NSMImageView *sender) {
        @nsm_strong(self)
        if (!self.deleteEnabled) return;
        if (((NSMPhotoImageView *)sender).isDeleting) return;
        
        self.addBtn.enabled = NO;
        for (UIView *view in self.subviews) {
            if ([view isKindOfClass:[NSMPhotoImageView class]]) {
                ((NSMPhotoImageView *)view).isDeleting = YES;
                ((NSMPhotoImageView *)view).deleteBtn.hidden = NO;
                [view.layer addAnimation:[self shakeAnimation] forKey:@"shakeAnimation"];
            }
        }
    };
    
    if (self.sortEnabled) {
        imageView.panActionBlock = ^(NSMImageView *sender, UIPanGestureRecognizer *pan) {
            
        };
    }
    
    // 删除
    imageView.deleteBtnActionBlock = ^(NSMPhotoImageView *sender) {
        @nsm_strong(self)
        [sender removeFromSuperview];
        [kPhotoViews removeObject:sender];
        if (self.photoViews.count == 0)
            self.addBtn.enabled = YES;
        [self checkVisibility];
        [self layoutAnimationWithDuration:0.25];
    };
}

#pragma mark - methods
- (void)applicationDidBecomeActive {
    self.addBtn.enabled = YES;
    for (UIView *view in self.subviews) {
        if ([view isKindOfClass:[NSMPhotoImageView class]]) {
            ((NSMPhotoImageView *)view).isDeleting = NO;
            ((NSMPhotoImageView *)view).deleteBtn.hidden = YES;
            [view.layer removeAllAnimations];
        }
    }
}

- (void)checkVisibility {
    if (_editEnabled && _photoViews.count<_maximumNumberOfPhotos)
        _addBtn.myVisibility = MyVisibility_Visible;
    else
        _addBtn.myVisibility = MyVisibility_Gone;
}

- (UIImage *)compressImage:(UIImage *)image {
    if (self.pictureQualityMode == NSMPictureQualityModeSD) {
        CGSize size = CGSizeZero;
        // 1.当前屏幕宽高比
        double scale_screen = kScreenWidth / kScreenHeight;
        // 2.图片的宽高比
        double scale_image = image.size.width / image.size.height;
        if (scale_image > scale_screen && image.size.width > kScreenWidth) {
            // 将宽度铺满
            size = CGSizeMake(kScreenWidth,  image.size.height*(kScreenWidth/image.size.width));
        } else if (scale_image < scale_screen && image.size.height > kScreenHeight) {
            // 将高度铺满
            size = CGSizeMake(image.size.width*(kScreenHeight/image.size.height), kScreenHeight);
        } else
            size = image.size;
        
        UIGraphicsBeginImageContext(size);
        [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
    // return UIImageJPEGRepresentation(image, 0.7);
    return image;
}

- (void)addImageViews:(NSArray<id<NSObject>> *)photos isOrigin:(BOOL)isOrigin {
    for (id<NSObject> obj in photos) {
        [self addSingleImageView:obj isOrigin:isOrigin photoEdit:nil];
    }
}

- (void)addSingleImageView:(id<NSObject>)obj isOrigin:(BOOL)isOrigin photoEdit:(LFPhotoEdit *)photoEdit {
    NSMPhotoImageView *imageView = [NSMPhotoImageView new];
    imageView.mark = obj;
    imageView.isOrigin = isOrigin;
    imageView.photoEdit = photoEdit;
    imageView.heightSize.equalTo(imageView.widthSize).multiply(_aspectRatio);
    if ([obj isKindOfClass:[NSString class]])
        [imageView setImageWithURL:[NSURL URLWithString:(NSString *)obj] placeholder:_placeholderImage];
    else if ([obj isKindOfClass:[NSURL class]])
        [imageView setImageWithURL:(NSURL *)obj placeholder:_placeholderImage];
    else if ([obj isKindOfClass:[UIImage class]])
        imageView.image = (UIImage *)obj;
    else if ([obj isKindOfClass:[NSData class]])
        imageView.image = [UIImage imageWithData:(NSData *)obj];
    
    [self addActionsForImageView:imageView];
    [self insertSubview:imageView atIndex:self.subviews.count-1];
    [kPhotoViews addObject:imageView];
    
    [self checkVisibility];
}

#pragma mark - 选取照片
- (void)addButtonDidClick {
    _isReplace = NO;
    [self.viewController.view endEditing:YES];
    
    UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:InternationalString(@"添加图片") message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *snap = [UIAlertAction actionWithTitle:InternationalString(@"相机拍照") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self snapImage];
    }];
    UIAlertAction *pick = [UIAlertAction actionWithTitle:InternationalString(@"相册选取") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self pickImage];
    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:InternationalString(@"取消") style:UIAlertActionStyleDefault handler:nil];
    
    if (self.addPictureMode & NSMAddPictureModeCamara) {
        [actionSheet addAction:snap];
    }
    if (self.addPictureMode & NSMAddPictureModeLibrary) {
        [actionSheet addAction:pick];
    }
    [actionSheet addAction:cancel];
    [self.viewController presentViewController:actionSheet animated:YES completion:nil];
}

- (void)imageViewDidTap:(NSMPhotoImageView *)imageView {
    _isReplace = YES;
    _currentImageView = imageView;
    [self.viewController.view endEditing:YES];
    
    UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:InternationalString(@"预览/编辑/替换") message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *browse = [UIAlertAction actionWithTitle:InternationalString(@"预览") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self browseImage];
    }];
    UIAlertAction *edit = [UIAlertAction actionWithTitle:InternationalString(@"编辑") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self editImage];
    }];
    UIAlertAction *snap = [UIAlertAction actionWithTitle:InternationalString(@"相机拍照替换") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self snapImage];
    }];
    UIAlertAction *pick = [UIAlertAction actionWithTitle:InternationalString(@"相册选取替换") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [self pickImage];
    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:InternationalString(@"取消") style:UIAlertActionStyleDefault handler:nil];
    [actionSheet addAction:browse];
    [actionSheet addAction:edit];
    if (self.addPictureMode & NSMAddPictureModeCamara) {
        [actionSheet addAction:snap];
    }
    if (self.addPictureMode & NSMAddPictureModeLibrary) {
        [actionSheet addAction:pick];
    }
    [actionSheet addAction:cancel];
    [self.viewController presentViewController:actionSheet animated:YES completion:nil];
}

// 预览
- (void)browseImage {
    NSMutableArray *array = @[].mutableCopy;
    NSInteger idx = 0;
    for (int i=0; i<_photoViews.count; i++) {
        NSMPhotoImageView *view = _photoViews[i];
        if ([view isEqual:_currentImageView]) {
            idx = i;
        }
        NSDictionary *dic = @{@"title": @"",
                              @"subtitle": @"",
                              @"photo": view.image?view.image:view.mark};
        [array addObject:dic];
    }
    [NSMPhotoBrowser showPhotos:array thumbs:nil atIndex:idx];
}

// 编辑(点击已有照片之后调用)
- (void)editImage {
    LFPhotoEditingController *lfPhotoEditVC = [LFPhotoEditingController new];
    lfPhotoEditVC.delegate = self;
    if (_currentImageView.photoEdit)
        lfPhotoEditVC.photoEdit = _currentImageView.photoEdit;
    else
        lfPhotoEditVC.editImage = _currentImageView.image;
    lfPhotoEditVC.operationType = (LFPhotoEditOperationType_draw |
                                   LFPhotoEditOperationType_splash |
                                   LFPhotoEditOperationType_filter |
                                   LFPhotoEditOperationType_crop);
    lfPhotoEditVC.defaultOperationType = LFPhotoEditOperationType_crop;
    NSNumber *ratio = @(LFPhotoEditOperationSubTypeCropAspectRatio1x1);
    lfPhotoEditVC.operationAttrs = @{LFPhotoEditCropAspectRatioAttributeName: ratio,
                                     LFPhotoEditCropCanRotateAttributeName: @(YES),
                                     LFPhotoEditCropCanAspectRatioAttributeName:@(NO)};
    [self.viewController.navigationController pushViewController:lfPhotoEditVC animated:NO];
    
    [self.viewController.navigationController setNavigationBarHidden:YES];
    [UIApplication sharedApplication].statusBarHidden = YES;
    [_keyWindow.rootViewController setNeedsStatusBarAppearanceUpdate];
}

// 编辑(照片选择器选中照片之后调用)
- (void)editImageFromPicker:(UIImage *)image {
    if (!image) return;
    
    LFPhotoEditingController *lfPhotoEditVC = [LFPhotoEditingController new];
    lfPhotoEditVC.delegate = self;
    lfPhotoEditVC.editImage = image;
    lfPhotoEditVC.operationType = (LFPhotoEditOperationType_draw |
                                   LFPhotoEditOperationType_splash |
                                   LFPhotoEditOperationType_filter |
                                   LFPhotoEditOperationType_crop);
    lfPhotoEditVC.defaultOperationType = LFPhotoEditOperationType_crop;
    NSNumber *ratio = @(LFPhotoEditOperationSubTypeCropAspectRatio1x1);
    lfPhotoEditVC.operationAttrs = @{LFPhotoEditCropAspectRatioAttributeName: ratio,
                                     LFPhotoEditCropCanRotateAttributeName: @(YES),
                                     LFPhotoEditCropCanAspectRatioAttributeName:@(NO)};
    [self.viewController.navigationController pushViewController:lfPhotoEditVC animated:NO];
    
    [self.viewController.navigationController setNavigationBarHidden:YES];
    [UIApplication sharedApplication].statusBarHidden = YES;
    [_keyWindow.rootViewController setNeedsStatusBarAppearanceUpdate];
}

// 相册
- (void)pickImage {
    if (_isReplace) {
        // 替换单选直接调用系统
        UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
        ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        ipc.delegate = self;
        [self.viewController presentViewController:ipc animated:YES completion:nil];
    } else {
        // 新增单张直接调用系统
        if (self.maximumNumberOfPhotos == 1) {
            UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
            ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            ipc.delegate = self;
            [self.viewController presentViewController:ipc animated:YES completion:nil];
            return;
        }
        // 新增多选
        ZYQAssetPickerController *picker = [ZYQAssetPickerController new];
        picker.maximumNumberOfSelection = _maximumNumberOfPhotos-_photoViews.count;
        picker.assetsFilter = [ALAssetsFilter allPhotos];
        picker.showEmptyGroups = NO;
        picker.delegate = self;
        picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            if ([[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) {
                NSTimeInterval duration = [[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyDuration] doubleValue];
                return duration >= 5;
            } else return YES;
        }];
        
        [self.viewController presentViewController:picker animated:YES completion:nil];
    }
}

// 拍照
- (void)snapImage {
    UIImagePickerController *ipc = [UIImagePickerController new];
    ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
    ipc.delegate = self;
    UIImage *image;
    [image imageAsset];
    [self.viewController presentViewController:ipc animated:YES completion:nil];
}

#pragma mark - 选取照片回调
- (UIImage *)normalizedImage:(UIImage *)image {
    return image;
    if (image.imageOrientation == UIImageOrientationUp) return image;
    
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    [image drawInRect:(CGRect){0, 0, image.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    // 如果是拍照,保存到手机相册
    if(picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
        UIImageWriteToSavedPhotosAlbum(image,nil,nil,nil);
    }
    // 照片选取完之后调用编辑
    @nsm_weak(self)
    [self.viewController dismissViewControllerAnimated:YES completion:^{
        @nsm_strong(self)
        // 纠正图片方向
        BOOL shouldCorrect = YES;
        if (shouldCorrect) {
            UIImage *correct = [self normalizedImage:image];
            [self editImageFromPicker:correct];
        } else {
            [self editImageFromPicker:image];
        }
    }];
}

- (void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets {
    // 只有多选才会到这里
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSMutableArray *newImages = @[].mutableCopy;
        for (int i=0; i<assets.count; i++) {
            ALAsset *asset = assets[i];
            UIImage *image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];
            [newImages addObject:image];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // 当只选了一张的时候启用编辑
            if (newImages.count==1) {
                [self editImageFromPicker:newImages.firstObject];
            } else {
                !self.photosDidChanged?:self.photosDidChanged();
                [self addImageViews:newImages isOrigin:NO];
            }
        });
    });
}

#pragma mark - 照片编辑回调
- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didCancelPhotoEdit:(LFPhotoEdit *)photoEdit {
    [self.viewController.navigationController popViewControllerAnimated:NO];
    [UIApplication sharedApplication].statusBarHidden = NO;
    [_keyWindow.rootViewController setNeedsStatusBarAppearanceUpdate];
}

- (void)lf_PhotoEditingController:(LFPhotoEditingController *)photoEditingVC didFinishPhotoEdit:(LFPhotoEdit *)photoEdit {
    [self.viewController.navigationController popViewControllerAnimated:NO];
    [UIApplication sharedApplication].statusBarHidden = NO;
    [_keyWindow.rootViewController setNeedsStatusBarAppearanceUpdate];
    
    if (_isReplace) {
        // 替换图片
        if (photoEdit) {
            // 图片已编辑,取编辑视图
            UIImage *image = photoEdit.editPreviewImage;
            _currentImageView.image = image;
            _currentImageView.isOrigin = NO;
            _currentImageView.mark = image;
            _currentImageView.photoEdit = photoEdit;
            !self.photosDidChanged?:self.photosDidChanged();
        } else {
            /**
             图片未编辑(此时有2种情况)
             1.图片被编辑过过,但是撤销了所有的编辑数据
             2.原图没有被编辑过,然后什么也没做
             */
            UIImage *image = photoEditingVC.editImage;
            _currentImageView.image = image;
            _currentImageView.isOrigin = NO;
            _currentImageView.mark = image;
            _currentImageView.photoEdit = photoEdit;
            !self.photosDidChanged?:self.photosDidChanged();
        }
    } else {
        // 新增图片
        UIImage *image = photoEdit?photoEdit.editPreviewImage:photoEditingVC.editImage;
        // 有可能选取的时候就编辑了图片
        [self addSingleImageView:image isOrigin:NO photoEdit:photoEdit];
        !self.photosDidChanged?:self.photosDidChanged();
    }
}

@end
